home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / iffparse / sift.c < prev   
C/C++ Source or Header  |  1992-09-03  |  8KB  |  238 lines

  1. ;/* sift.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -j73 sift.c
  3. Blink FROM LIB:c.o,sift.o TO sift LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. */
  6.  
  7. /*
  8. Copyright (c) 1992 Commodore-Amiga, Inc.
  9.  
  10. This example is provided in electronic form by Commodore-Amiga, Inc. for
  11. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  12. published by Addison-Wesley (ISBN 0-201-56774-1).
  13.  
  14. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  15. information on the correct usage of the techniques and operating system
  16. functions presented in these examples.  The source and executable code
  17. of these examples may only be distributed in free electronic form, via
  18. bulletin board or as part of a fully non-commercial and freely
  19. redistributable diskette.  Both the source and executable code (including
  20. comments) must be included, without modification, in any copy.  This
  21. example may not be published in printed form or distributed with any
  22. commercial product.  However, the programming techniques and support
  23. routines set forth in these examples may be used in the development
  24. of original executable software products for Commodore Amiga computers.
  25.  
  26. All other rights reserved.
  27.  
  28. This example is provided "as-is" and is subject to change; no
  29. warranties are made.  All use is at your own risk. No liability or
  30. responsibility is assumed.
  31. */
  32.  
  33.  
  34. /*
  35. *
  36. * sift.c:       Takes any IFF file and tells you what's in it.  Verifies syntax and all that cool stuff.
  37. *
  38. * Usage: sift -c                ; For clipboard scanning
  39. *    or  sift <file>            ; For DOS file scanning
  40. *
  41. * Reads the specified stream and prints an IFFCheck-like listing of the contents of the IFF file, if any.
  42. * Stream is a DOS file for <file> argument, or is the clipboard's primary clip for -c.
  43. * This program must be run from a CLI.
  44. *
  45. */
  46.  
  47. #include <exec/types.h>
  48. #include <exec/memory.h>
  49. #include <libraries/dos.h>
  50. #include <libraries/iffparse.h>
  51. #include <clib/exec_protos.h>
  52. #include <clib/dos_protos.h>
  53. #include <clib/iffparse_protos.h>
  54. #include <stdlib.h>
  55. #include <stdio.h>
  56. #include <string.h>
  57.  
  58. #ifdef LATTICE
  59. int CXBRK(void) { return(0); }     /* Disable Lattice CTRL/C handling */
  60. int chkabort(void) { return(0); }  /* really */
  61. #endif
  62.  
  63. #define MINARGS 2
  64.  
  65. UBYTE vers[] = "\0$VER: sift 37.1";       /* 2.0 Version string for c:Version to find */
  66. UBYTE usage[] = "Usage: sift IFFfilename (or -c for clipboard)";
  67.  
  68. void PrintTopChunk (struct IFFHandle *);  /* proto for our function */
  69.  
  70. /*
  71.  * Text error messages for possible IFFERR_#? returns from various IFF routines.  To get the index into
  72.  * this array, take your IFFERR code, negate it, and subtract one.
  73.  *  idx = -error - 1;
  74.  */
  75. char    *errormsgs[] = {
  76.         "End of file (not an error).", "End of context (not an error).", "No lexical scope.",
  77.         "Insufficient memory.", "Stream read error.", "Stream write error.",
  78.         "Stream seek error.", "File is corrupt.", "IFF syntax error.",
  79.         "Not an IFF file.", "Required call-back hook missing.", "Return to client.  You should never see this."
  80. };
  81.  
  82. struct Library *IFFParseBase;
  83.  
  84. void main(int argc, char **argv)
  85. {
  86.     struct IFFHandle    *iff = NULL;
  87.     long                error;
  88.     short               cbio;
  89.  
  90.         /* if not enough args or '?', print usage */
  91.         if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?'))
  92.                 {
  93.                 printf("%s\n",usage);
  94.                 goto bye;
  95.                 }
  96.  
  97.         /* Check to see if we are doing I/O to the Clipboard. */
  98.         cbio = (argv[1][0] == '-'  &&  argv[1][1] == 'c');
  99.  
  100.         if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L)))
  101.                 {
  102.                 puts("Can't open iff parsing library.");
  103.                 goto bye;
  104.                 }
  105.  
  106.         /* Allocate IFF_File structure. */
  107.         if (!(iff = AllocIFF ()))
  108.                 {
  109.                 puts ("AllocIFF() failed.");
  110.                 goto bye;
  111.                 }
  112.  
  113.         /*
  114.          * Internal support is provided for both AmigaDOS files, and the clipboard.device.  This bizarre
  115.          * 'if' statement performs the appropriate machinations for each case.
  116.          */
  117.         if (cbio)
  118.                 {
  119.                 /*
  120.                  * Set up IFF_File for Clipboard I/O.
  121.                  */
  122.                 if (!(iff->iff_Stream =
  123.                                 (ULONG) OpenClipboard (PRIMARY_CLIP)))
  124.                         {
  125.                         puts ("Clipboard open failed.");
  126.                         goto bye;
  127.                         }
  128.                 InitIFFasClip (iff);
  129.                 }
  130.         else
  131.                 {
  132.                 /* Set up IFF_File for AmigaDOS I/O.  */
  133.                 if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE)))
  134.                         {
  135.                         puts ("File open failed.");
  136.                         goto bye;
  137.                         }
  138.                 InitIFFasDOS (iff);
  139.                 }
  140.  
  141.         /* Start the IFF transaction. */
  142.         if (error = OpenIFF (iff, IFFF_READ))
  143.                 {
  144.                 puts ("OpenIFF failed.");
  145.                 goto bye;
  146.                 }
  147.  
  148.         while (1)
  149.                 {
  150.                 /*
  151.                  * The interesting bit.  IFFPARSE_RAWSTEP permits us to have precision monitoring of the
  152.                  * parsing process, which is necessary if we wish to print the structure of an IFF file.
  153.                  * ParseIFF() with _RAWSTEP will return the following things for the following reasons:
  154.                  *
  155.                  * Return code:                 Reason:
  156.                  * 0                            Entered new context.
  157.                  * IFFERR_EOC                   About to leave a context.
  158.                  * IFFERR_EOF                   Encountered end-of-file.
  159.                  * <anything else>              A parsing error.
  160.                  */
  161.                 error = ParseIFF (iff, IFFPARSE_RAWSTEP);
  162.  
  163.                 /*
  164.                  * Since we're only interested in when we enter a context, we "discard" end-of-context
  165.                  * (_EOC) events.
  166.                  */
  167.                 if (error == IFFERR_EOC)
  168.                         continue;
  169.                 else if (error)
  170.                         /*
  171.                          * Leave the loop if there is any other error.
  172.                          */
  173.                         break;
  174.  
  175.  
  176.                 /* If we get here, error was zero. Print out the current state of affairs. */
  177.                 PrintTopChunk (iff);
  178.                 }
  179.  
  180.         /*
  181.          * If error was IFFERR_EOF, then the parser encountered the end of
  182.          * the file without problems.  Otherwise, we print a diagnostic.
  183.          */
  184.         if (error == IFFERR_EOF)
  185.                 puts ("File scan complete.");
  186.         else
  187.                 printf ("File scan aborted, error %ld: %s\n",
  188.                         error, errormsgs[-error - 1]);
  189.  
  190. bye:
  191.         if (iff) {
  192.                 /* Terminate the IFF transaction with the stream.  Free all associated structures. */
  193.                 CloseIFF (iff);
  194.  
  195.                 /*
  196.                  * Close the stream itself.
  197.                  */
  198.                 if (iff->iff_Stream)
  199.                         if (cbio)
  200.                                 CloseClipboard ((struct ClipboardHandle *)
  201.                                                 iff->iff_Stream);
  202.                         else
  203.                                 Close (iff->iff_Stream);
  204.  
  205.                 /* Free the IFF_File structure itself. */
  206.                 FreeIFF (iff);
  207.                 }
  208.         if (IFFParseBase)       CloseLibrary (IFFParseBase);
  209.  
  210.         exit (RETURN_OK);
  211. }
  212.  
  213. void
  214. PrintTopChunk (iff)
  215. struct IFFHandle *iff;
  216. {
  217.         struct ContextNode      *top;
  218.         short                   i;
  219.         char                    idbuf[5];
  220.  
  221.         /* Get a pointer to the context node describing the current context. */
  222.         if (!(top = CurrentChunk (iff)))
  223.         return;
  224.  
  225.     /*
  226.      * Print a series of dots equivalent to the current nesting depth of chunks processed so far.
  227.      * This will cause nested chunks to be printed out indented.
  228.      */
  229.     for (i = iff->iff_Depth;  i--; )
  230.         printf (". ");
  231.  
  232.     /* Print out the current chunk's ID and size. */
  233.     printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
  234.  
  235.     /* Print the current chunk's type, with a newline. */
  236.     puts (IDtoStr (top->cn_Type, idbuf));
  237. }
  238.